package com.smartplatform.security.handlers;

import com.smartplatform.cache.RoleCache;
import com.smartplatform.event.LoginEvent;
import com.smartplatform.mapper.SysUserRoleMapper;
import com.smartplatform.pojo.MyBaseUser;
import com.smartplatform.pojo.SysMenu;
import com.smartplatform.pojo.SysRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author 咕唧
 * @Date 2022/6/7 10:22
 * @Version 1.0
 */
@Component
public class MyUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    private SysUserRoleMapper sysUserRoleMapper;

    private RoleCache roleCache;

    private ApplicationContext context;

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Autowired
    public void setRoleCache(RoleCache roleCache) {
        this.roleCache = roleCache;
    }

    @Autowired
    public void setSysUserRoleMapper(SysUserRoleMapper sysUserRoleMapper) {
        this.sysUserRoleMapper = sysUserRoleMapper;
    }

    /**
     * 当认证（登陆）成功之后执行
     *
     * @param request
     * @param response
     * @param authentication
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //注意不要写super,否则会提示这个错误 java.lang.IllegalStateException: 提交响应后无法调用sendRedirect（）
        //重定向到首页
        response.sendRedirect("/index.html");
        //这个的返回值就是spring里面的user,也就是我们userdetailservice中的返回值
        MyBaseUser principal = (MyBaseUser) authentication.getPrincipal();
        //在这里才能确认用户登录成功,然后根据用户的数据获取到用户的角色,然后能获取到用户的权限,设置给用户
        Long userId = principal.getUserId();
        //根据用户的id查询到所有的角色id
        List<Long> roleIds = sysUserRoleMapper.selectRoleIdByUserId(userId);
//        for (Long roleId : roleIds) {
//            System.err.println(roleId);
//        }
        //根据对应的角色id,查询到所有的角色
        //集合,用于保存用户所有权限的集合
        List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
        //System.err.println(authentication);
        roleIds.forEach(roleId -> {
            //根据角色id获取角色
            SysRole sysRole = roleCache.get(roleId);
            //根据角色id获取菜单
            List<SysMenu> menuList = sysRole.getMenuList();
            //根据菜单获取用户权限
            List<SimpleGrantedAuthority> list = menuList.stream()
                    .peek(System.err::println)
                    .map(SysMenu::getPerms)
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toList());
            authorityList.addAll(list);
        });
//        List<SimpleGrantedAuthority> authorityList = roleIds.stream().flatMap(roleId ->
//                roleCache.get(roleId).getMenuList().stream())
//                .map(SysMenu::getPerms)
//                .map(SimpleGrantedAuthority::new)
//                .collect(Collectors.toList());

        //重新给当前用户设置权限
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(principal, authentication.getCredentials(), authorityList));
        //登陆成功发送事件
        context.publishEvent(new LoginEvent(LoginEvent.LoginType.SUCCESS, principal.getUsername()));
    }


}
